﻿using DBUtil;
using DBUtil.Provider.MySql;
using LiveCharts;
using LiveCharts.Configurations;
using LiveCharts.Defaults;
using LiveCharts.WinForms;
using LiveCharts.Wpf;
using log4net;
using Sunny.UI;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.Windows.Interop;
using System.Windows.Media;
using static System.Net.WebRequestMethods;

namespace JFBG
{
    public partial class UdpMain : Form
    {

        bool debug = true;
        const int DEBUG_W = 1;//警告
        const int DEBUG_I = 2;//信息
        const int DEBUG_E = 3;//错误
        const int DEBUG_S = 4;//统计
        [DllImport("kernel32.dll")]
        public static extern Boolean AllocConsole();
        [DllImport("kernel32.dll")]
        public static extern Boolean FreeConsole();

        private void DebugWriteLine(string p, int type)
        {
            if (debug)
            {
                Console.BackgroundColor = ConsoleColor.Black;
                switch (type)
                {
                    case DEBUG_E://错误
                        Console.ForegroundColor = ConsoleColor.Red;
                        break;
                    case DEBUG_W://警告
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        break;
                    case DEBUG_S://统计
                        Console.ForegroundColor = ConsoleColor.Blue;
                        break;
                    case DEBUG_I://信息
                        Console.ForegroundColor = ConsoleColor.White;
                        break;
                }
                Console.WriteLine(p);
                Console.ForegroundColor = ConsoleColor.White;
            }
        }

        public const int RECEIVE = 1;
        public const int SEND = 2;
        //安全调用
        delegate void AddMessageToListCallback(string name, byte[] content, int type);
        delegate void timeCallback(object sender, System.Timers.ElapsedEventArgs e);
        //服务器套接字
        private static Socket serverSocket;
        //是否开启了服务
        private bool isServer = false;
        //监听线程
        [DisallowNull]
        private Thread receiveTh;

        private bool isSyncSet = false;

        private long countR = 0, countT = 0;

        private System.Timers.Timer timer { get; set; }//定时器，用来作为更新图标动态生成用

        private Random R { get; set; }//为了给Y值提供随机值

        //定时刷新曲线
        private System.Windows.Forms.Timer timerChart;

        private long times = 30;

        //X轴值数量初始值
        private long xCount = 60;
        //X轴值最大计数值
        private long xTimes = 60;
        //显示时长
        private long showTimes = 60;//(秒)

        //当前时间
        private long lastTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
        private long lastTime1 = DateTimeOffset.Now.ToUnixTimeMilliseconds();
        private long lastTime2 = DateTimeOffset.Now.ToUnixTimeMilliseconds();
        private long lastTime3 = DateTimeOffset.Now.ToUnixTimeMilliseconds();
        //采样频率
        private long frequency = 1;
        //采集间隔
        private long intervalTime = 1000;//(毫秒)
        //通道初始值
        private int channelIndex = 0;
        //通道初始值
        private int rasterIndex = 0;
        //光栅总数
        private int rasterCount = 16;
        //通道总数
        private int channelCount = 16;

        private MySqlAccess db;

        private string tableName = "raster_wave_normal";
        private int timeoutSeconds = 60 * 30;
        private int notifyAfter = 0;
        private Func<long, Task<bool>> callBack;
        private CancellationToken cancellationToken = default;

        private static readonly ILog log = LogManager.GetLogger(typeof(UdpMain));

        public UdpMain()
        {
            //初始化界面
            InitializeComponent();

            InitIntfaceData();

            R = new Random();
            if (debug)
            {
                AllocConsole();
                DebugWriteLine("控制台已打开！\n时间：" + DateTime.Now.ToString(
                        "[yyyy-MM-dd HH:mm:ss.fff] "), DEBUG_I);
            }

            DBUtil.DBFactory.AddDBSupport<DBUtil.Provider.MySql.MySqlDBFactory>();
            //db = MySqlDBFactory.CreateDB("Server=47.121.221.151;Database=jfbg;Uid=root;Pwd=qwer@1234;AllowLoadLocalInfile=true;SslMode=none;AllowPublicKeyRetrieval=True;Charset=utf8mb4;",
            //db = MySqlDBFactory.CreateDB("Server=127.0.0.1;Database=jfbg;Uid=user;Pwd=Abc123,.;AllowLoadLocalInfile=true;SslMode=none;AllowPublicKeyRetrieval=True;Charset=utf8mb4;",
            db = MySqlDBFactory.CreateDB("Server=127.0.0.1;Database=jfbg;Uid=user;Pwd=123456;AllowLoadLocalInfile=true;SslMode=none;AllowPublicKeyRetrieval=True;Charset=utf8mb4;",
                DBSetting.NewInstance().SetSqlMonitor(arg =>
                {
                    log.Info(arg);
                    return Task.CompletedTask;
                })
            );
        }


        private void InitIntfaceData()
        {
            //得到主机名
            string HostName = Dns.GetHostName();
            if (debug)
            {
                DebugWriteLine("主机名：" + HostName, DEBUG_I);
            }
            //通过主机名获取IP
            IPHostEntry IpEntry = Dns.GetHostEntry(HostName);
            //可变数组
            ArrayList addressList = new ArrayList();

            addressList.Add("0.0.0.0");
            addressList.Add("127.0.0.1");

            for (int i = 0; i < IpEntry.AddressList.Length; i++)
            {
                //从IP地址列表中筛选出IPv4类型的IP地址
                //AddressFamily.InterNetwork表示此IP为IPv4,
                //AddressFamily.InterNetworkV6表示此地址为IPv6类型
                if (IpEntry.AddressList[i].AddressFamily == AddressFamily.InterNetwork)
                {
                    if (debug)
                    {
                        DebugWriteLine("IPV4:" + IpEntry.AddressList[i].ToString(), DEBUG_I);
                    }
                    addressList.Add(IpEntry.AddressList[i].ToString());
                }
            }
            //固定大小
            addressList.TrimToSize();
            object[] adList = new object[addressList.Count];
            for (int i = 0; i < addressList.Count; i++)
            {
                adList[i] = addressList[i];
            }
            this.cbServerAddress.Items.AddRange(adList);
            this.cbServerAddress.SelectedIndex = 0;

        }

        //给消息列表添加消息
        private void AddMessageToList(string name, byte[] content, int type)
        {
            if (this.rtbMessageList.IsDisposed)
            {
                return;
            }
            //处理InvokeRequired，安全调用
            if (this.rtbMessageList.InvokeRequired)
            {
                AddMessageToListCallback d = new AddMessageToListCallback(AddMessageToList);
                this.Invoke(d, new object[] { name, content, type });
            }
            else
            {
                string str = "";
                string show = "";
                int i = 0;
                StringBuilder sb = new StringBuilder();
                foreach (byte b in content)
                {
                    //{0:X2} 大写
                    sb.AppendFormat("{0:x2}", b);
                }
                show = sb.ToString();
                if (debug)
                {
                    DebugWriteLine("共" + i + "个字符", DEBUG_I);
                }

                //构建消息头
                switch (type)
                {
                    case RECEIVE:
                        this.countR += i;
                        this.rtbMessageList.SelectionColor = System.Drawing.Color.Red;
                        str = DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss.fff] ") + " 收到：" + name + "\n";
                        break;
                    case SEND:
                        this.countT += i;
                        this.rtbMessageList.SelectionColor = System.Drawing.Color.Orange;
                        str = DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss.fff] ") + " 发自：" + name + "\n";
                        break;
                }

                //写入消息头
                this.rtbMessageList.AppendText(str);

                //写入消息内容
                this.rtbMessageList.SelectionColor = System.Drawing.Color.Black;

                this.rtbMessageList.AppendText(show);
                this.rtbMessageList.AppendText("\r\n");

                this.lbCount.Text = "接收：" + this.countR + " 发送：" + this.countT;

                if (debug)
                {
                    if (type == SEND)
                    {
                        DebugWriteLine("发送消息！发到：" + name + "    内容：" + show, DEBUG_I);
                    }
                    else
                    {
                        DebugWriteLine("收到消息！来自：" + name + "    内容：" + show, DEBUG_I);
                    }
                }
            }
        }

        //点击“开启服务按钮”
        private void btnOpenServer_Click(object sender, EventArgs e)
        {
            //停用按钮，防止多次点击
            this.btnOpenServer.Enabled = false;
            if (debug)
            {
                DebugWriteLine("停用按钮！", DEBUG_I);
            }
            //如果服务是打开的
            if (this.isServer)
            {
                if (debug)
                {
                    DebugWriteLine("服务器处于打开状态！", DEBUG_S);
                }
                //如果套接字不为空
                if (serverSocket != null)
                {
                    //先关闭线程，再关闭服务器
                    //this.receiveTh.Interrupt();
                    if (debug)
                    {
                        DebugWriteLine("关闭服务器！", DEBUG_I);
                    }
                    //关闭
                    serverSocket.Close();
                }

                //设置界面为服务关闭状态
                this.lbServerState.Text = "服务器已关闭";
                this.lbServerState.ForeColor = System.Drawing.Color.Blue;
                this.btnOpenServer.Text = "打开服务端口";
                this.pbServerState.BackgroundImage = global::JFBG.Properties.Resources.close;
                //允许编辑端口
                this.tbServerPort.Enabled = true;
                //允许编辑地址
                this.cbServerAddress.Enabled = true;

                //设置服务为关闭状态
                this.isServer = false;
                this.tbAbverseIp.Enabled = true;
                this.tbAbversePort.Enabled = true;
            }
            else
            {
                //如果服务是关闭的
                serverSocket = null;
                if (debug)
                {
                    DebugWriteLine("服务器处于关闭状态！", DEBUG_S);
                }
                //获取地址
                string ip = getIPAddress(cbServerAddress.Text);
                if (ip == null)
                {
                    if (debug)
                    {
                        DebugWriteLine("服务器地址不正确", DEBUG_E);
                    }
                    MessageBox.Show("服务器地址不正确，请输入IP或者域名！\n域名需要有DNS服务器！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    DebugWriteLine("启用按钮！", DEBUG_I);
                    this.btnOpenServer.Enabled = true;
                    return;
                }
                if (debug)
                {
                    DebugWriteLine("服务器地址：" + ip, DEBUG_S);
                }
                int port = getPort(tbServerPort.Text);
                if (port == -1)
                {
                    if (debug)
                    {
                        DebugWriteLine("服务器端口格式不对！", DEBUG_E);
                    }
                    MessageBox.Show("服务器端口格式不对！（值：0 - 65535）", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    if (debug)
                    {
                        DebugWriteLine("启用按钮！", DEBUG_I);
                    }
                    this.btnOpenServer.Enabled = true;
                    return;
                }

                if (debug)
                {
                    DebugWriteLine("服务器端口：" + port, DEBUG_S);
                }

                try
                {
                    if (debug)
                    {
                        DebugWriteLine("服务器打开中......", DEBUG_I);
                    }
                    //创建套接字，以UDP的方式
                    serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                    //绑定端口号和IP
                    serverSocket.Bind(new IPEndPoint(IPAddress.Parse(ip), port));
                }
                catch (SocketException es)
                {
                    //出现异常
                    if (debug)
                    {
                        DebugWriteLine("出现异常：" + es.ErrorCode + "！", DEBUG_E);
                    }
                    MessageBox.Show("绑定端口时出现异常：" + es.ErrorCode + "！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    if (debug)
                    {
                        DebugWriteLine("启用按钮！", DEBUG_S);
                    }
                    //按钮启用
                    btnOpenServer.Enabled = true;
                }
                //如果打开了并且绑定端口了
                if (serverSocket != null && serverSocket.IsBound)
                {
                    if (debug)
                    {
                        DebugWriteLine("服务器开启成功！", DEBUG_I);
                    }

                    //UI显示
                    //设置界面为服务打开状态
                    this.lbServerState.Text = "服务器已开启";
                    this.lbServerState.ForeColor = System.Drawing.Color.Red;
                    this.btnOpenServer.Text = "关闭服务";
                    this.pbServerState.BackgroundImage = global::JFBG.Properties.Resources.open;
                    //不允许编辑端口
                    this.tbServerPort.Enabled = false;
                    //不允许编辑地址
                    this.cbServerAddress.Enabled = false;
                    //设置服务为打开状态
                    this.isServer = true;

                    this.tbAbverseIp.Enabled = false;
                    this.tbAbversePort.Enabled = false;
                    //开启接收消息线程
                    this.receiveTh = new Thread(ReciveMsg);
                    this.receiveTh.Start();
                }
            }

            if (debug)
            {
                DebugWriteLine("启用按钮！", DEBUG_S);
            }
            this.btnOpenServer.Enabled = true;
        }

        //发送数据报
        private void btnSendMessage_Click(object sender, EventArgs e)
        {
            if (!isServer)
            {
                MessageBox.Show("请先打开服务端口！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            //表示这个是不是服务器的套接字
            bool isUseServer = false;
            Socket clientSocket = null;
            //停用按钮，防止多次点击
            this.btnSendMessage.Enabled = false;
            if (debug)
            {
                DebugWriteLine("停用按钮！", DEBUG_S);
            }
            //如果服务是打开的
            if (this.isServer && (serverSocket != null))
            { //并且服务器和发送的设置是一样的
                isUseServer = true;
                //直接使用服务器的套接字
                clientSocket = serverSocket;
            }
            else
            {//如果服务是关闭的,或者设置不同
                string myIp = getIPAddress(this.tbAbverseIp.Text);//获取地址
                if (myIp == null)
                {
                    if (debug)
                    {
                        DebugWriteLine("发送端地址不正确", DEBUG_E);
                    }
                    MessageBox.Show("发送端地址不正确，请输入IP或者域名！\n域名需要有DNS服务器！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    DebugWriteLine("启用按钮！", DEBUG_I);
                    this.btnSendMessage.Enabled = true;
                    return;
                }
                if (debug)
                {
                    DebugWriteLine("发送端地址：" + myIp, DEBUG_S);
                }
                int myPort = getPort(this.tbAbversePort.Text);
                if (myPort == -1)
                {
                    if (debug)
                    {
                        DebugWriteLine("发送端端口格式不对！", DEBUG_E);
                    }
                    MessageBox.Show("发送端端口格式不对！（值：0 - 65535）", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    if (debug)
                    {
                        DebugWriteLine("启用按钮！", DEBUG_I);
                    }
                    this.btnSendMessage.Enabled = true;
                    return;
                }

                if (debug)
                {
                    DebugWriteLine("发送端端口：" + myPort, DEBUG_S);
                }
                //创建套接字
                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                //绑定端口号和IP
                clientSocket.Bind(new IPEndPoint(IPAddress.Parse(myIp), myPort));
            }
            //获取地址
            string adIp = getIPAddress(this.tbAbverseIp.Text);
            if (adIp == null)
            {
                if (debug)
                {
                    DebugWriteLine("对方主机地址不正确", DEBUG_E);
                }
                MessageBox.Show("对方主机地址不正确，请输入IP或者域名！\n域名需要有DNS服务器！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                if (debug)
                {
                    DebugWriteLine("启用按钮！", DEBUG_I);
                }
                this.btnSendMessage.Enabled = true;
                return;
            }
            if (debug)
            {
                DebugWriteLine("对方主机地址：" + adIp, DEBUG_S);
            }
            //对方端口
            int adPort = getPort(this.tbAbversePort.Text);
            if (adPort == -1)
            {
                if (debug)
                {
                    DebugWriteLine("对方主机端口格式不对！", DEBUG_E);
                }
                MessageBox.Show("对方主机端口格式不对！（值：0 - 65535）", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                if (debug)
                {
                    DebugWriteLine("启用按钮！", DEBUG_I);
                }
                this.btnSendMessage.Enabled = true;
                return;
            }

            if (debug)
            {
                DebugWriteLine("接收端端口：" + adPort, DEBUG_S);
            }
            //设置好地址
            EndPoint adversePoint = new IPEndPoint(IPAddress.Parse(adIp), adPort);
            try
            {
                string msg = this.btnSendMessage.Text;
                if ((!string.IsNullOrEmpty(msg)) && ("开始采集".Equals(msg)))
                {
                    //如果不为空
                    byte[] bmsg = { 0x01, 0x0A, 0x55 };
                    //发送数据包
                    clientSocket.SendTo(bmsg, adversePoint);
                    //UI显示
                    AddMessageToList(adversePoint.ToString(), bmsg, SEND);
                    this.btnSendMessage.Text = "停止采集";
                }
                else
                {
                    byte[] bmsg = { 0x01, 0x0A, 0x00 };
                    //发送数据包
                    clientSocket.SendTo(bmsg, adversePoint);
                    //UI显示
                    AddMessageToList(adversePoint.ToString(), bmsg, SEND);
                    this.btnSendMessage.Text = "开始采集";
                }
            }
            catch (SocketException es)
            {
                if (debug)
                {
                    DebugWriteLine("出现异常：" + es.ErrorCode + "！", DEBUG_E);
                }
                MessageBox.Show("发送数据报时出现异常：" + es.ErrorCode + "！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            //如果是新开的套接字
            if (!isUseServer)
            {
                if (clientSocket != null)
                {
                    //用完之后关掉
                    clientSocket.Close();
                }
            }
            if (debug)
            {
                DebugWriteLine("启用按钮！", DEBUG_S);
            }
            this.btnSendMessage.Enabled = true;
        }

        // 接收发送给本机IP对应端口号的数据报
        private void ReciveMsg()
        {
            try
            {
                while (this.isServer)
                {
                    //用来保存发送方的IP和端口号
                    EndPoint point = new IPEndPoint(IPAddress.Any, 0);
                    //消息缓存区申请
                    byte[] buffer = new byte[512];
                    //接收数据报
                    int length = serverSocket.ReceiveFrom(buffer, ref point);
                    if (debug)
                    {
                        DebugWriteLine("接收数据长度 length：" + length, DEBUG_I);
                    }
                    byte[] revBuf = new byte[length];
                    Buffer.BlockCopy(buffer, 0, revBuf, 0, length);
                    //显示在消息列表里
                    //AddMessageToList(point.ToString(), revBuf, RECEIVE);
                    //显示在波形图里
                    this.ReciveWaveDataOPM(revBuf);
                }
            }
            catch (SocketException e)
            {
                DebugWriteLine(e.Message, DEBUG_E);
            }
        }


        //窗口关闭事件委托，在窗口关闭事件前处理
        private void UdpForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.isServer = false;
            if (this.receiveTh != null)
            {
                if (debug)
                {
                    DebugWriteLine("关闭接收线程！", DEBUG_I);
                }
                //receiveTh.Interrupt();
            }
            if (serverSocket != null)
            {
                if (debug)
                {
                    DebugWriteLine("关闭服务器！", DEBUG_I);
                }
                serverSocket.Close();
            }
            if (debug)
            {
                DebugWriteLine("关闭窗口！", DEBUG_I);
            }
        }

        //清空消息列表
        private void btnClearList_Click(object sender, EventArgs e)
        {
            if (debug)
            {
                DebugWriteLine("清空消息列表！", DEBUG_I);
            }
            this.rtbMessageList.Text = "";
        }

        //清空输入框
        private void btnClearInput_Click(object sender, EventArgs e)
        {
            if (debug)
            {
                DebugWriteLine("清空输入框！", DEBUG_I);
            }
        }

        //根据字符串获取端口
        private int getPort(string str)
        {
            if (!IsPort(str))
            {
                //不是端口
                return -1;
            }
            //转换成整型
            int port = Convert.ToInt32(str);
            if (port >= 0 && port <= 65535)
            {
                //如果是合法端口
                return port;
            }
            else
            {//不是合法端口
                return -1;
            }
        }

        //根据字符串获取IP地址
        string getIPAddress(string str)
        {
            if (!IsIP(str))
            {
                //如果不是IP
                if (IsDomain(str))
                {
                    //如果是域名
                    try
                    {
                        //解析域名
                        IPAddress[] host = Dns.GetHostAddresses(str);
                        //域名解析的IP地址
                        IPAddress ipAddress = host[0];
                        //改成IP地址
                        str = ipAddress.ToString();
                    }
                    catch
                    {
                        return null;
                    }
                }
                else
                {
                    return null;
                }
            }
            //返回IP地址
            return str;
        }

        // 验证字符串是否是域名
        public bool IsDomain(string str)
        {
            string pattern = @"^(?=^.{3,255}$)[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$";
            return IsMatch(pattern, str);
        }

        // 验证字符串是否是IP
        bool IsIP(string str)
        {
            string pattern = @"(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)";
            return IsMatch(pattern, str);
        }

        //判断是否为0-65535的数字
        bool IsPort(string str)
        {
            string pattern = @"^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$";
            return IsMatch(pattern, str);
        }

        // 判断一个字符串，是否匹配指定的表达式(区分大小写的情况下)
        public bool IsMatch(string expression, string str)
        {
            Regex reg = new Regex(expression);
            if (string.IsNullOrEmpty(str))
            {
                return false;
            }
            return reg.IsMatch(str);
        }

        //同步地址事件
        private void cbServerAddress_TextChanged(object sender, EventArgs e)
        {

        }

        //同步端口事件
        private void tbServerPort_TextChanged(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// 实现自动下拉
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void rtbMessageList_TextChanged(object sender, EventArgs e)
        {
            this.rtbMessageList.SelectionStart = rtbMessageList.Text.Length;
            this.rtbMessageList.ScrollToCaret();
        }

        private void lbHelp_Click(object sender, EventArgs e)
        {
            MessageBox.Show("这个程序是一个UDP收发器，能接收和发送UDP报文。\nUDP广播地址：***.***.***.255\n2020-4 Minuy.top 网络编程作业\n开源地址：https://gitee.com/minuy/udp-transceiver", "帮助", MessageBoxButtons.OK);
        }

        private void CartesianChart1OnDataClick(object sender, ChartPoint chartPoint)
        {
            MessageBox.Show("You clicked (" + chartPoint.X + "," + chartPoint.Y + ")");
        }

        private ChartValues<DateTimePoint> InitChartValuesData()
        {
            ChartValues<DateTimePoint> chartValues = new ChartValues<DateTimePoint>();
            for (long i = 1; i <= 30; i++)
            {
                chartValues.Add(new DateTimePoint(i, R.NextDouble()));
            }
            return chartValues;
        }

        //OPM-T1622F 光栅解调仪设备通信协议解析
        private void ReciveWaveDataOPM(byte[] revData)
        {
            long nowTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
            string datetime = (new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds((long)nowTime).ToLocalTime()).ToString("yyyy-MM-dd HH:mm:ss");
            int index = 0;
            byte head = revData[index++];
            byte cmd = revData[index++];

            if (cmd == 0x02)
            {

            }
            else if (cmd == 0x04)
            {

            }
            else if (cmd == 0x06)
            {

            }
            else if (cmd == 0x07)
            {

            }
            else if (cmd == 0x08)
            {

            }
            else if (cmd == 0x0A)
            {

            }
            else if (cmd == 0x0C)
            {
                try
                {
                    DataTable table = new DataTable();
                    table.Columns.Add("collect_time", typeof(long));
                    table.Columns.Add("collect_datetime", typeof(string));
                    table.Columns.Add("channel_id", typeof(int));
                    table.Columns.Add("raster_count", typeof(int));
                    table.Columns.Add("wave_length1", typeof(double));
                    table.Columns.Add("wave_length2", typeof(double));
                    table.Columns.Add("wave_length3", typeof(double));
                    table.Columns.Add("wave_length4", typeof(double));
                    table.Columns.Add("wave_length5", typeof(double));
                    table.Columns.Add("wave_length6", typeof(double));
                    table.Columns.Add("wave_length7", typeof(double));
                    table.Columns.Add("wave_length8", typeof(double));
                    table.Columns.Add("wave_length9", typeof(double));
                    table.Columns.Add("wave_length10", typeof(double));
                    table.Columns.Add("wave_length11", typeof(double));
                    table.Columns.Add("wave_length12", typeof(double));
                    table.Columns.Add("wave_length13", typeof(double));
                    table.Columns.Add("wave_length14", typeof(double));
                    table.Columns.Add("wave_length15", typeof(double));
                    table.Columns.Add("wave_length16", typeof(double));

                    for (int channelId = 1; channelId <= channelCount; channelId++)
                    {
                        index++;
                        byte rasterCnt = revData[index++];
                        if (rasterCnt > 0)
                        {
                            byte[] tempArray = new byte[2 * rasterCnt];
                            Array.Copy(revData, index, tempArray, 0, 2 * rasterCnt);

                            string[] countValues = new string[rasterCount];
                            double[] waveLengths = new double[rasterCnt];
                            for (byte rasterID = 0; rasterID < rasterCnt; rasterID++)
                            {
                                byte[] tempArray1 = new byte[2];
                                Array.Copy(tempArray, 2 * rasterID, tempArray1, 0, 2);

                                uint valueL = tempArray1[0];
                                uint valueH = tempArray1[1];
                                double waveLength = (double)DivideAndRound((valueL + valueH * 256), 1000, 5) + 1520;
                                waveLengths[rasterID] = waveLength;
                            }

                            table.Rows.Add(nowTime, datetime, channelId, rasterCnt, waveLengths[0], waveLengths[1], waveLengths[2], waveLengths[3], waveLengths[4], waveLengths[5], waveLengths[6], waveLengths[7],
                                    waveLengths[8], waveLengths[9], waveLengths[10], waveLengths[11], waveLengths[12], waveLengths[13], waveLengths[14], waveLengths[15], waveLengths[16]);
                        }
                        index = index + 2 * rasterCnt;
                        if (index >= revData.Length)
                        {
                            break;
                        }
                    }
                    if (table.Rows.Count > 0)
                    {
                        //保存到数据库
                        saveRasterWaveToDBAsync(table);
                    }
                }
                catch (Exception ex)
                {

                }
            }
            else if (cmd == 0x14)
            {

            }
            else if (cmd == 0x16)
            {

            }
            else if (cmd == 0x17)
            {

            }
            else if (cmd == 0x24)
            {

            }
            else if (cmd == 0x26)
            {

            }
            else if (cmd == 0x2E)
            {

            }
            else if (cmd == 0x30)
            {

            }
            else if (cmd == 0x32)
            {

            }
            else if (cmd == 0x34)
            {

            }
            else
            {
            }
        }

        private async Task saveRasterWaveToDBAsync(DataTable table)
        {
            long nowTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
            log.Debug("saveRasterWaveToDBAsync start time :" + nowTime + " table :" + table.ToString());
            await db.BulkCopyAsync(table, tableName, timeoutSeconds, notifyAfter, callBack, cancellationToken);
            long endTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
            log.Debug("saveRasterWaveToDBAsync end time :" + endTime);
        }

        public static decimal DivideAndRound(decimal dividend, decimal divisor, int decimalPlaces)
        {
            if (divisor == 0)
            {
                throw new DivideByZeroException();
            }
            decimal result = dividend / divisor;
            return Math.Round(result, decimalPlaces);
        }

        //应变计算公式：ε＝[（W1－A1）- ((W2－A2)/ K2) * K3] /K1
        //其中：W1 为应变光栅当前测量波长，A1 为应变光栅安装完成后初始波长
        // W2 为温度光栅当前测量波长，A2 为温度光栅安装完成后初始波长
        // K1 为应变系数， K2 为温度光栅温度系数，K3 为应变光栅温度系数
        private static double CalculateStress(double W1, double W2, double A1, double A2, double K1, double K2, double K3)
        {
            double stress = (((W1 - A1) - ((W2 - A2) / K2) * K3) / K1) * 1000;

            return Math.Round(stress, 4);
        }

        //计算公式：A =[(Wa - Wa0)-(Wb-Wb0)]/k
        //其中：	Wa—a光栅测试波长(小波长)         Wa0—a光栅零点波长
        //          Wb—b光栅测试波长(大波长）        Wb0—b光栅零点波长
        //备注：初始波长不能以报告的初始波长，安装的时候要以当前环境读出来的波长为初始波长
        private static double CalculateAngle(double Wa, double Wa0, double Wb, double Wb0, double K)
        {
            double stress = ((Wa - Wa0) - (Wb - Wb0)) / K;

            return Math.Round(stress, 4);
        }

        //公式：加速度A =（W1－A1）/K
        //A为加速度，W1是测试波长，A1是原始波长，K是加速度灵敏度
        private static double CalculateAcceleration(double W1, double A1, double K)
        {
            double stress = ((W1 - A1) / K) * 1000;

            return Math.Round(stress, 4);
        }

        //位移计算公式：△L=A((λ1-λ2)-(λ10-λ20))²+B((λ1-λ2)-(λ10- λ20))+C
        // 上式中：A,B,C 为多项式系数
        // △L 为仪器长度变化量，单位 mm
        // λ1、λ2 为当前光栅的波长，单位 nm
        // λ10、λ20 为初始光栅的波长(必须用“计算参数”两光栅波长),单位 nm
        private static double CalculateDisplacement(double λ1, double λ2, double λ10, double λ20, double A, double B, double C)
        {
            double stress = A * Math.Pow(((λ1 - λ2) - (λ10 - λ20)), 2) + B * ((λ1 - λ2) - (λ10 - λ20)) + C;

            return Math.Round(stress, 4);
        }
    }

    public class RasterWaveNormal
    {
        //采集时间
        public long collect_time { get; set; }
        //收集日期时间
        public string collect_datetime { get; set; }
        //通道ID
        public int channel_id { get; set; }
        //传感器数量
        public int raster_count { get; set; }
        //光栅波长1
        public double wave_length1 { get; set; }
        //光栅波长2
        public double wave_length2 { get; set; }
        //光栅波长3
        public double wave_length3 { get; set; }
        //光栅波长4
        public double wave_length4 { get; set; }
        //光栅波长5
        public double wave_length5 { get; set; }
        //光栅波长6
        public double wave_length6 { get; set; }
        //光栅波长7
        public double wave_length7 { get; set; }
        //光栅波长8
        public double wave_length8 { get; set; }
        //光栅波长9
        public double wave_length9 { get; set; }
        //光栅波长10
        public double wave_length10 { get; set; }
        //光栅波长11
        public double wave_length11 { get; set; }
        //光栅波长12
        public double wave_length12 { get; set; }
        //光栅波长13
        public double wave_length13 { get; set; }
        //光栅波长14
        public double wave_length14 { get; set; }
        //光栅波长15
        public double wave_length15 { get; set; }
        //光栅波长16
        public double wave_length16 { get; set; }

        public override string ToString()
        {
            return collect_time + ", " + collect_datetime + ", " + channel_id + ", " + raster_count
                + ", " + wave_length1 + ", " + wave_length2 + ", " + wave_length3 + ", " + wave_length4 + ", " + wave_length5 + ", " + wave_length6 + ", " + wave_length7 + ", " + wave_length8
                + ", " + wave_length9 + ", " + wave_length10 + ", " + wave_length11 + ", " + wave_length12 + ", " + wave_length13 + ", " + wave_length14 + ", " + wave_length15 + ", " + wave_length16;
        }
    }

}
